#include <stdio.h>
#include <math.h>

#define MIN(x,y)  ((x)<(y)?(x):(y))

#define MIN_TEMP 000.0
#define MAX_TEMP 760.0    /* make multiple of 5 * temp_step */
#define TEMP_STEP  4  /* two steps pre temp */
#define NUM_ENTRIES ((unsigned long)(1+(MAX_TEMP-MIN_TEMP)/TEMP_STEP))

#define NUM_GASES 8

float   ref_temp[] = { 226.7, 229.1, 250.0, 200.0, 283.0, 229.0, 200.0,    220.0 };
float   ref_visc[] = { 255.9, 126.0, 285.3, 322.3, 323.3, 263.8, 322.3,    260.0 };
float   exponent[] = { 0.702, 0.682, 0.680, 0.780, 0.739, 0.740, 0.780,    0.700 };
char    *gas_name[] = { "N2",  "H2",  "He",  "ArMe", "O2", "Air",  "Argon", "???" };


#define ETA_TABLE_SCALING       128
#define ETA_T_TABLE_SCALING     128
#define CF_P_RATIO_SCALING     8192


float Viscosity ( float v_ref, float t_ref, float t, float exp )
{
      return v_ref * pow( t/t_ref, exp );
}
 
float TempFromEtaT( float v_ref, float t_ref, float eta_t, float exp )
{
    eta_t = eta_t * 0x1000000;

    /* printf ( "\n\nv_ref %8.1f  t_ref %8.1f  exp   %4.3f  eta_t %12.1f\n", v_ref, t_ref, exp, eta_t ); */

    return pow( (eta_t * pow( t_ref, exp ) / ( ETA_T_TABLE_SCALING * v_ref )), (1 / ( 1 + exp )) );
}

int  main( void )
{


    double t, visc;
 
    int i,j,z;



     printf ( "\n" );
     printf ( "#pragma SECTION CONST=flow3\n" );
     printf ( "\n" );


    printf ( "const float Viscosity_Exp[] = {\n" );

    for ( i = 0 ; i < NUM_GASES; i++ )
    {
         printf( "    /* %6s */ %4.3f, \n", gas_name[i], exponent[i] );
    }
    printf( "};\n\n\n" );



    printf ( "const float Ref_Viscosity[] = {\n" );

    for ( i = 0 ; i < NUM_GASES; i++ )
    {
         printf( "    /* %6s */ %4.1f, \n", gas_name[i], ref_visc[i] );
    }
    printf( "};\n\n\n" );



    printf ( "const float Visc_Ref_Temp[] = {\n" );

    for ( i = 0 ; i < NUM_GASES; i++ )
    {
         printf( "    /* %6s */ %4.1f, \n", gas_name[i], 273.15+ref_temp[i] );
    }
    printf( "};\n\n\n" );


    printf ( "#define MIN_TEMP  %f\n", MIN_TEMP );
    printf ( "#define MAX_TEMP  %f\n", MAX_TEMP );
    printf ( "#define TEMP_STEP %d\n", TEMP_STEP );
    printf ( "\f\n" );




    printf( "#define ETA_TABLE_SCALING %d\n", ETA_TABLE_SCALING );
 
    printf ( "const U_INT16 Eta_Table [ /* num gases */ ] [ %d ] = {\n", NUM_ENTRIES );

    for ( i = 0 ; i < NUM_GASES ; i++ )
    {
         printf ( " { /* %s   exponent = %4.3f */ \n", gas_name[i], exponent[i] );
     
         z = 0;
         for ( t = MIN_TEMP ; t < MAX_TEMP ; t += TEMP_STEP )
         {
             visc = ETA_TABLE_SCALING * Viscosity( ref_visc[i], (ref_temp[i]+273.15)*64, t*64 , exponent[i] );
             if ( visc == 0 ) visc = 1;   /* avoid divide by zeros */
             if ( (z%5) == 0 )
             {
                  printf ( "\n/* T=%4.0fK %4.0fC */ 0x%04x, ", t,t-273.15, (unsigned int)visc );
             }
             else
             {
                  printf ( "0x%04x, ", (unsigned int)visc );
             }
             z++;
          
         }
             visc = ETA_TABLE_SCALING * Viscosity( ref_visc[i], (ref_temp[i]+273.15)*64, t*64 , exponent[i] );
             if ( i < NUM_GASES-1 ) printf ( "0x%04x },\n\n\f", (unsigned int)visc );
             else                 printf ( "0x%04x } \n\n\n", (unsigned int)visc );
    }
     
    printf( "};\n\n\f\n" );




    printf( "#define ETA_T_TABLE_SCALING %d\n", ETA_T_TABLE_SCALING );

 
    printf ( "const U_INT32 Eta_T_Table [ /* num gases */ ] [ %d ] = {\n", NUM_ENTRIES );

    for ( i = 0 ; i < NUM_GASES ; i++ )
    {
         printf ( " { /* %s   exponent = %4.3f */ \n", gas_name[i], 1+exponent[i] );
     
         z = 0;
         for ( t = MIN_TEMP ; t < MAX_TEMP ; t += TEMP_STEP )
         {
             visc = ETA_T_TABLE_SCALING * t * 64 *Viscosity( ref_visc[i], (ref_temp[i]+273.15)*64, t*64 , exponent[i] );
             if ( visc == 0 ) visc = 1;  /* avoid divide by zeros */
             if ( (z%5) == 0 )
             {
                  printf ( "\n/* T=%4.0fK %4.0fC */ 0x%08lx, ", t, t-273.15, (unsigned long)visc );
             }
             else
             {
                  printf ( "0x%08lx, ", (unsigned long)visc );
             }
             z++;
         }
             visc = ETA_T_TABLE_SCALING * t * 64 *Viscosity( ref_visc[i], (ref_temp[i]+273.15)*64, t*64 , exponent[i] );
             if ( i < NUM_GASES-1 ) printf ( "0x%08lx },\n\n\f", (unsigned long)visc );
             else                 printf ( "0x%08lx } \n\n\n", (unsigned long)visc );
    }
     
    printf( "};\n\n\f\n" );



    printf( "#define CF_P_RATIO_SCALING %d\n", CF_P_RATIO_SCALING );
 
    printf ( "const U_INT16 Const_Flow_P_Ratio_Table [ /* num gases */ ] [ %d ] = {\n", NUM_ENTRIES );

    for ( i = 0 ; i < NUM_GASES ; i++ )
    {
         printf ( " {\n\n\n /* %s   exponent = %4.3f */ \n", gas_name[i], 1.0+exponent[i] );
     
         z = 0;
         for ( t = MIN_TEMP ; t < MAX_TEMP ; t += TEMP_STEP )
         {
             if ( (z%5) == 0 )
             {
                  printf ( "\n/* T=%4.0fK %4.0fC */ 0x%04x, ", t, t-273.15, (unsigned int)(CF_P_RATIO_SCALING * pow( t/298.15, 1.0+exponent[i] )) );
             }
             else
             {
                  printf ( "0x%04x, ",    (unsigned int)(CF_P_RATIO_SCALING * pow( t/298.15, 1.0 + exponent[i] )) );
             }
             z++;
         }
             if ( i < NUM_GASES-1 ) printf ( "0x%04x },\f", (unsigned int)(CF_P_RATIO_SCALING * pow( t/298.15, 1.0 + exponent[i])));
             else                 printf ( "0x%04x } ",   (unsigned int)(CF_P_RATIO_SCALING * pow( t/298.15, 1.0 + exponent[i])));
    }
     
    printf( "};\n\n\f\n" );




#define ROOT_TABLE_STEP_SIZE   0x1000000
#define NUM_ROOT_ENTRIES       257

 
    printf ( "const U_INT16 Temp_Root_Table [ /* num gases */ ] [ %d ] = {\n", NUM_ROOT_ENTRIES );

    for ( i = 0 ; i < NUM_GASES ; i++ )
    {
         printf ( " {\n\n\n /* %s   exponent = %4.3f */ \n", gas_name[i], 1+exponent[i] );
     
         z = 0;
         for ( j = 0 ; j < 256 ; j += 1 )
         {
             t = j * 0x1000000;

             if ( (z%5) == 0 )
             {
                  printf ( "\n/* T ^ x = %08x */ 0x%04x, ", (unsigned long)t, 
                         (unsigned int) MIN(TempFromEtaT( ref_visc[i], (ref_temp[i]+273.15)*64, j, exponent[i] ),0xffff) );
             }
             else
             {
                  printf ( "0x%04x, ",  
                         (unsigned int) MIN(TempFromEtaT( ref_visc[i], (ref_temp[i]+273.15)*64, j, exponent[i] ),0xffff) );
             }
             z++;
         }
             t = (float)0xffffffff;
             if ( i < NUM_GASES-1 ) printf ( "0x%04x },\n\f",
                         (unsigned int) MIN(TempFromEtaT( ref_visc[i], (ref_temp[i]+273.15)*64, j, exponent[i] ), 0xffff) );
             else                   printf ( "0x%04x } ",   
                         (unsigned int) MIN(TempFromEtaT( ref_visc[i], (ref_temp[i]+273.15)*64, j, exponent[i] ), 0xffff) );
    }
     
    printf( "};\n\n\f\n" );


   printf ( "#pragma SECTION UNDO\n" );

    return 0;

}

